分享一些平时经典查错手段,人生苦短,我们的目标是,电话通知出bug后,秒登vpn,千里之外定位问题,瞬息之间修复上线,今天不加班
Nginx 日常排查
根据不同问题,要选择合适的方法,最简单的方法还是查看 error_log
,有些怪异的问题,从error_log
中中能找到蛛丝马迹。慢请求相关的问题,可通过access_log
记录请求时间。如果log中没有什么有用信息,可以尝试分析下系统调用,或网络。程序本身的问题,可能需要gdb调试。
0x01 检查 error_log
error_log 提供了异常丰富的信息,比如nginx处理请求出错,网络连接出错,后端返回出错,系统调用出错等各种错误信息,如果是线下调试,则可以开启debug信息,便于调试排查
connect
,write
,read timeout
等网络超时错误Permission denied
,File not found
等系统调用错误- HTTP状态码
400
,499
,500
等对应的错误
HTTP 503
503 Service Temporarily Unavailable
故障检测: 先定位到前端故障服务器节点,在前端服务器上ping后端服务器查看网络延迟丢包情况,后端服务端口响应时间。如发现延迟>100ms,丢包>5%。说明前端到后端网络出现问题。HTTP 503 Service Temporarily Unavailable
故障一般是前端访问后端网络延迟导致。首选排查是不是后端流量过载导致。如果不是,就是前端到后端网络问题。
HTTP 504
504 Gateway Time-out
故障检测: 查看后端服务器Nginx php mysql资源占用情况,并查看相关错误日志。此类故障几率比较小HTTP 504 Gateway Time-out
故障一般是因的后端服务器响应超时。如PHP程序执行时间太长,数据库查询超时。与程序沟通是否需要增加PHP 执行超时时间。
0x02 检查 access_log
access_log 提供了客户端访问日志,nginx 的access_log可灵活定义日志格式,日志内容,比如后端响应时间,后端返回状态码,后端的failover过程等,另外,也可根据access_log 进行统计,比如根据接口统计,根据客户端IP统计,根据服务端IP统计,根据后端响应时间统计等。
- 统计HTTP状态码比例,从而知道nginx服务状况
- 统计响应时间,判断超时请求
- 根据经验,如果响应时间分布集中在某个数字,并且标准差很小,则很可能是因为超时。
- 统计
QPS
, 对比负载是否均衡
Nginx做反向代理,有时发现某些接口较慢,通常在3s左右
nginx access_log
可以记录upstream_response_time
- 分析
access_log
的upstream_response_time
,发现响应大约3s
多 - 分析后端
access_log
,处理时间在毫秒级别 - 最终发现,问题是由于
nginx
跟后端connect
较慢导致
truss、strace或ltrace查看系统调用
strace和truss用来 用来跟踪系统调用,并可以打印丰富的信息,比如系统调用发生的时间,调用耗时,传参的内容,调用返回结果等等。
truss是早期为System V R4开发的调试程序,包括Aix、FreeBSD在内的大部分Unix系统都自带了这个工具;而strace最初是为SunOS系统编写的,这两个工具现在也已被移植到了大部分Unix系统中,大多数Linux发行版都自带了strace和ltrace,
ltrace用来 跟踪进程调用库函数的情况,ltrace最早出现在GNU/Debian Linux中。
1 | -f :除了跟踪当前进程外,还跟踪其子进程。 |
使用上述三个参数基本上就可以完成大多数调试任务了,下面举几个命令行例子:1
2truss -o ls.truss ls -al: 跟踪ls -al的运行,将输出信息写到文件/tmp/ls.truss中。
strace -f -o vim.strace vim: 跟踪vim及其子进程的运行,将输出信息写到文件vim.strace。
另一个十分有用的功能参数-c:
1 | // 各项含义如下: |
案例一 futex
表示很可能发生了死锁
1 | [pushaowei@kidsguard ~]$ sudo strace -p 1477 |
案例二 处理PHP
请求过慢
可以用strace
来验证系统调用耗时,在一次排查PHP问题时,发现有时PHP
处理请求过慢,strace –T
发现是flock
调用过慢。1
2
31516867165.279482 flock(4, LOCK_EX) = 0 < 0.389046 >
1516867165.668528 write(4, "1\t1\t1403674085\t11"..., 76) = 76 <0 .000037 >
1516867165.668565 flock(4, LOCK_UN) = 0 <<0.000017>
综合分析
web服务器访问慢通常是以下几类问题:
- 系统资源不足检查服务器CPU/内存/IO/带宽是否成为瓶颈,异常情况也不要放过,比如CPU单核占用过高,内存时高时低等
- 内核、程序参数设置不合理看看有没有报内核错误,连接数用户打开文件数这些有没有达到上限等等
- 链路本身慢是否跨运营商、用户上下行带宽不够、dns解析慢、服务器内网广播风暴什么的
- 程序设计不合理是否程序本身算法设计太差,数据库语句太过复杂
- 其它关联的程序引起的如果要访问数据库,检查一下是否数据库访问慢
- 是否被攻击了查看服务器是否被DDOS了等等
- 硬件故障这个一般直接服务器就挂了,而不是访问慢某些故障会伴随一些其它现象发生,比如说CPU过高/内存过高/网络带宽被打满/nf_contrack表设置过低的时候你会发现SSH上去敲命令都很慢。排查思路没有固定的套路,不过某些经验和知识能够加快你的定位问题的速度,应该先把能想到的都加上监控项,然后结合报警、经验利用控制变量法具体分析。